package com.ff.javamonkey.socket.message;

import java.text.CharacterIterator;
import java.text.StringCharacterIterator;

/**
 * This class is the designated message send to the server,
 * encapsulated with the proper packing.
 * @author rhama_arya
 */
public class Message {
	// Debugging
	private final String TAG = "Message";
	// Message fields
	private char command;
	private int messageLength;
	private char[] encodedMessage;
	private char[][] multiEncodedMessage;
	
	// Static fields for Command
	public static char ACRL_UPDATE = 0x01;
	public static char FDCU_DBUPDATE = 0x02;
	public static char RSYNC_ACRLDATA = 0x03;
	public static char SEND_MESSAGE = 0x04;
	public static char UPDATE_ACRLDATA_STATUS = 0x05; // updating a status on a downloaded file.
	public static char CHILD_INIT = 0xfa;
	public static char CHILD_DONE = 0xfb;
	public static char REQUEST_QUIT = 0xfc;
	public static char PING_COMMAND = 0xfd;
	
	/**
	 * Default constructor
	 */
	public Message() {
		
	}
	
	/**
	 * Construct a Message object with a command, and a message.
	 * @param command
	 * @param message
	 */
	public Message(char command, String message) {
		this.command = command;
		this.encodedMessage = encodeMessage(message);
		this.messageLength = encodedMessage.length;
	}
	
	/**
	 * Construct a Message object with a command, to update file status in the ACRLdb
	 */
	public Message(char command, String[] message) {
		for (String st: message) {
			
		}
	}
	
	public Message(char command, String str, String parentName, String aircraft, String fileId, String fileName, String fileStatus) {
		this.command = command;
		this.encodedMessage = splitMessage(str+"|"+parentName+"|"+aircraft+"|"+fileId+"|"+fileName+"|"+fileStatus);
		this.messageLength = encodedMessage.length;
	}
	
	public char[][] getMultiEncodedMessage() {
		return multiEncodedMessage;
	}

	public void setMultiEncodedMessage(char[][] multiEncodedMessage) {
		this.multiEncodedMessage = multiEncodedMessage;
	}
	
	private char[] splitMessage(String str) {
		CharacterIterator it = new StringCharacterIterator(str);
		char[] results = new char[str.length()];
		int i = 0;
		for (char ch = it.first(); ch != CharacterIterator.DONE; ch = it.next()) {
			results[i++] = ch;
		}
		return results;
	}

	/**
	 * This method's purpose is to encode the message before sending it.
	 * @param str String to be encoded.
	 * @return encoded String. For example, a "String" string would be encoded as "|S|t|r|i|n|g"
	 */
	private char[] encodeMessage(String str) {
		CharacterIterator it = new StringCharacterIterator(str);
		//StringBuffer results = new StringBuffer();
		char[] results = new char[str.length()*2];
		int i = 0;
		for (char ch = it.first(); ch != CharacterIterator.DONE; ch = it.next()) {
			results[i++] = '|';
			results[i++] = ch;
		}
		return results;
	}
	
	/**
	 * This method's purpose is to decode the message so it's human readable.
	 * @param str String to be decoded.
	 * @return decoded String.
	 */
	public String decodeMessage(String str) {
		String results = str;
		return results.toString();
	}
	
	/**
	 * This method's purpose is to decode the command so it's human readable.
	 * @param int int code to be decoded. NOTE that we're using integer.
	 * @return decoded Command
	 */
	public static String decodeCommand(int i) {
		if (i == (int)PING_COMMAND) {
			return "PING_COMMAND";
		}
		return "UNDEFINED";
	}

	public char getCommand() {
		return command;
	}

	public void setCommand(char command) {
		this.command = command;
	}

	public int getMessageLength() {
		return messageLength;
	}

	public void setMessageLength(int messageLength) {
		this.messageLength = messageLength;
	}

	public char[] getEncodedMessage() {
		return encodedMessage;
	}

	public void setMessage(String message) {
		this.encodedMessage = encodeMessage(message);
	}

	public static String decodeByte(byte readByte) {
		System.out.println(readByte);
		return Byte.toString(readByte);
	}
}
